#define MAX_USERNAME_LEN 20
#define MAX_PASSWORD_LEN 20
#define MAX_PHONE_LEN 15
#define MAX_ADDRESS_LEN 100
#define MAX_DESCRIPTION_LEN 200
#define MAX_SHELF_CODE_LEN 10
#define MAX_PICKUP_CODE_LEN 10
#define MAX_ORDER_ID_LEN 20
typedef enum {
    PACKAGE_NORMAL = 1,     // 普通包裹
    PACKAGE_LARGE = 2,      // 大件包裹
    PACKAGE_FRAGILE = 3,    // 易碎包裹
    PACKAGE_FRESH = 4,      // 生鲜/冷链包裹
    PACKAGE_VALUABLE = 5,   // 贵重包裹
    PACKAGE_STORAGE = 6     // 寄存包裹
} PackageType;
typedef struct {
    Package* packageList;
    Shelf* shelfList;
    // 权限配置映射表
} SystemData;
typedef enum {
    STATUS_RECEIVED = 1,    // 已入库
    STATUS_NOTIFIED = 2,    // 已通知
    STATUS_PICKED = 3,      // 已取走
    STATUS_EXPIRED = 4,     // 超期未取
    STATUS_DAMAGED = 5,     // 已破损
    STATUS_LOST = 6,        // 已丢失
    STATUS_RETURNED = 7     // 已退回
} PackageStatus;
typedef struct Package {
    char orderId[MAX_ORDER_ID_LEN];//包裹ID
    char receiverPhone[MAX_PHONE_LEN];//收件人
    char senderPhone[MAX_PHONE_LEN];//寄件人
    char description[MAX_DESCRIPTION_LEN];//备注（用于标注异常状态，寄件要求等等）
    PackageType type;
    PackageStatus status;
    char shelfCode[MAX_SHELF_CODE_LEN];       // 存放位置编码
    char pickupCode[MAX_PICKUP_CODE_LEN];     // 取件码
    // time_t receiveTime;                       // 入库时间
    // time_t notifyTime;                        // 通知时间
    // time_t pickupTime;                        // 取件时间
    float weight;                             // 包裹重量
    float fee;                                // 费用
    // 取件相关信息
    char pickedUpByPhone[MAX_PHONE_LEN];      // 实际取件人手机号
    char pickedUpByUsername[MAX_USERNAME_LEN]; // 实际取件人用户名
    int isProxyPickup;                        // 是否代取，1表示是，0表示否
    char proxyRelation[MAX_DESCRIPTION_LEN];  // 代取关系说明(如同学、室友、亲属等)
    
    struct Package* next;
} Package;
typedef struct Shelf {
    char code[MAX_SHELF_CODE_LEN];            // 货架编码
    int capacity;                             // 总容量
    int occupied;                             // 已占用数量
    int supportTypes[6];                      // 支持的包裹类型数组，对应PackageType枚举的值，1表示支持，0表示不支持
    int isSpecialized;                        // 是否为专用货架，1表示是，0表示否
    struct Shelf* next;
} Shelf;
/**
 * 生成取件码
 * 
 * @return 随机生成的取件码
 */
char* generatePickupCode();
/**
 * 包裹入库
 * 
 * @param data 系统数据结构指针
 * @param orderId 订单号
 * @param receiverPhone 收件人手机号
 * @param senderPhone 寄件人手机号
 * @param description 包裹描述
 * @param type 包裹类型
 * @param weight 包裹重量
 * @param currentUser 当前操作用户
 * @return 成功返回生成的取件码，失败返回NULL
 */
char* receivePackage(SystemData* data, char* orderId, char* receiverPhone, 
                    char* senderPhone, char* description, PackageType type, 
                    float weight, User* currentUser) ;
/**
 * 计算包裹费用
 * 
 * @param type 包裹类型
 * @param weight 包裹重量
 * @param userType 用户类型
 * @return 计算的费用
 */
float calculatePackageFee(PackageType type, float weight, int vipLevel);
/**
 * 添加货架
 * 
 * @param data 系统数据结构指针
 * @param code 货架编码
 * @param capacity 容量
 * @param supportTypes 支持的包裹类型数组，对应PackageType枚举的值，1表示支持，0表示不支持
 * @param isSpecialized 是否为专用货架，1表示是，0表示否
 * @param currentUser 当前操作用户
 * @return 成功返回1，失败返回0
 */
int addShelf(SystemData* data, char* code, int capacity, 
            int supportTypes[6], int isSpecialized, User* currentUser);//集中管理数据
/**
 * 包裹出库(取件)
 * 
 * @param data 系统数据结构指针
 * @param pickupCode 取件码
 * @param phone 取件人手机号
 * @param username 取件人用户名
 * @param isProxy 是否代取
 * @param proxyRelation 如果是代取，代取关系说明
 * @param currentUser 当前操作用户
 * @return 成功返回1，失败返回0
 */
int pickupPackage(SystemData* data, char* pickupCode, char* phone, char* username, 
                 int isProxy, char* proxyRelation, User* currentUser);
/**
 * 根据取件码查询包裹
 * 
 * @param data 系统数据结构指针
 * @param pickupCode 取件码
 * @return 找到返回包裹指针，未找到返回NULL
 */
Package* findPackageByPickupCode(SystemData* data, char* pickupCode);
/**
 * 根据手机号查询包裹列表
 * 
 * @param data 系统数据结构指针
 * @param phone 手机号
 * @param status 包裹状态过滤，0表示查询所有状态
 * @param packageCount 输出参数，返回找到的包裹数量
 * @return 包裹指针数组，使用完毕需要手动释放
 */
Package** findPackagesByPhone(SystemData* data, char* phone, PackageStatus status, int* packageCount);
/**
 * 根据订单号查询包裹
 * 
 * @param data 系统数据结构指针
 * @param orderId 订单号
 * @return 找到返回包裹指针，未找到返回NULL
 */
Package* findPackageByOrderId(SystemData* data, char* orderId);
/**
 * 更新包裹状态
 * 
 * @param data 系统数据结构指针
 * @param orderId 订单号
 * @param newStatus 新状态
 * @param currentUser 当前操作用户
 * @return 成功返回1，失败返回0
 */
int updatePackageStatus(SystemData* data, char* orderId, 
                       PackageStatus newStatus, User* currentUser);//用于管理员以及快递员更新快递状态使用。
/**
 * 处理异常包裹(破损、丢失等)
 * 
 * @param data 系统数据结构指针
 * @param orderId 订单号
 * @param status 异常状态
 * @param remark 备注说明
 * @param needCompensation 是否需要赔偿
 * @param compensationAmount 赔偿金额(如果需要)
 * @param currentUser 当前操作用户
 * @return 成功返回1，失败返回0
 */
int handleAbnormalPackage(SystemData* data, char* orderId, PackageStatus status, 
                        char* remark, int needCompensation, float compensationAmount, User* currentUser);
/**
 * 计算包裹费用
 * 
 * @param type 包裹类型
 * @param weight 包裹重量
 * @param userType 用户类型
 * @param vipLevel VIP等级(如适用)
 * @return 计算的费用
 */
float calculatePackageFee(PackageType type, float weight, UserType userType, int vipLevel);

/**
 * 检查并处理超期未取包裹
 * 
 * @param data 系统数据结构指针
 * @param expiryDays 超期天数
 * @param expiredCount 输出参数，返回超期包裹数量
 * @return 成功返回1，失败返回0
 */
int handleExpiredPackages(SystemData* data, int expiryDays, int* expiredCount);
/**
 * 包裹冒领/误领的追溯与处理
 * 
 * @param data 系统数据结构指针
 * @param orderId 订单号
 * @param reporterPhone 报告人手机号
 * @param description 情况描述
 * @param currentUser 当前操作用户
 * @return 成功返回处理结果描述，失败返回NULL
 */
char* handleWrongPickup(SystemData* data, char* orderId, char* reporterPhone, 
                      char* description, User* currentUser);//输出冒领者的信息，将备注标记为冒领处理后，由管理员进行更正
/**
 * 查询用户已取包裹历史
 * 
 * @param data 系统数据结构指针
 * @param phone 用户手机号
 * @param startDate 开始日期，NULL表示不限
 * @param endDate 结束日期，NULL表示不限
 * @param packageCount 输出参数，返回找到的包裹数量
 * @return 包裹指针数组，使用完毕需要手动释放
 */
Package** findUserPickupHistory(SystemData* data, char* phone, 
                              char* startDate, char* endDate, int* packageCount);//包含代取包裹
/**
 * 统计各类包裹数量
 * 
 * @param data 系统数据结构指针
 * @param startDate 开始日期(格式：YYYY-MM-DD)
 * @param endDate 结束日期(格式：YYYY-MM-DD)
 * @return 包含统计结果的字符串，使用完毕需要手动释放
 */
char* statisticsPackagesByType(SystemData* data, char* startDate, char* endDate);
/**
 * 检查货架容量预警
 * 
 * @param data 系统数据结构指针
 * @param warningThreshold 预警阈值(百分比)
 * @param packageType 指定包裹类型的货架预警，为0时检查所有货架
 * @param shelfCount 输出参数，返回预警货架数量
 * @return 返回需要预警的货架编码数组，使用完毕需要手动释放
 */
char** checkShelfCapacityWarning(SystemData* data, 
                               float warningThreshold, PackageType packageType, int* shelfCount);//后者穿指针用于返回货架预警量。